/*
 * Modbus app for RTU.
 * Copyright (c) 2012  apleilx
 * All rights reserved.
 * no limite
 */

/* ----------------------- Platform includes --------------------------------*/
#define _MAPP_MODULE_
#include "mbapp.h"
#include "os_obj.h" // RTOS object definitions
#include "sys_task.h"
#include "common.h"
#include "bsp_api.h"

#define TEST_MODE MB_RTU_SLAVE

mb_baud_tab_create;

uint8_t mbTestErrCnt = 0;
uint8_t mbTestOkCnt = 0;

typedef struct
{
	uint16_t reg_r[64];
	uint16_t reg_w[64];
	uint16_t pv_r[64];
	uint16_t pv_w[64];
	uint16_t obj_size;
} mb_tst_type;

mb_tst_type mb_tst;

void qc_task(const void *argv);

/******************************************************************************
 * @brief   mb handle.
 * @param   none
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void modbus_task(const void *argv)
{
	mb_cmd_buff_type mcmd;

	qc_task(argv);

	mb_obj_init(&mb.obj04);

	// master config
	mb04_Init(MB_RTU_SLAVE, mb_baud_tab[MB_BAUD_115200], MB_PAR_NONE);
	mb.obj04.slave_id = 1;
	mb.obj04.rtu_master_delay_set = 3;
	mb.obj04.rcv_end_handle_comp = 0;
	mb.obj04.os_event_send = mb_os_send;
	mb.obj04.os_event_base = 2 << 4;
	mb.obj04.rtu_len_cut = 1;

	mb_obj_init(&mb.obj03);

	// master config
	mb03_Init(MB_RTU_MASTER, mb_baud_tab[MB_BAUD_115200], MB_PAR_NONE);
	mb.obj03.slave_id = 1;
	mb.obj03.rtu_master_delay_set = 3;
	mb.obj03.rcv_end_handle_comp = 0;
	mb.obj03.os_event_send = mb_os_send;
	mb.obj03.os_event_base = 2 << 4;
	mb.obj03.rtu_len_cut = 1;

	// cmd config
	mcmd.device_id = 1;
	mcmd.cmd = FUN_CODE_READ_COILS;
	mcmd.dat = mb_tst.pv_w;
	mcmd.dat_addr = 0;
	mcmd.amount = 48;
	mcmd.call_back = 0;
	mb.obj03.api->stc_cmd_req(0, &mcmd);

	mcmd.cmd = FUN_CODE_READ_DISCRETE;
	mb.obj03.api->stc_cmd_req(1, &mcmd);

	mcmd.cmd = FUN_CODE_W_R_MULTIPLE_REG;
	mb.obj03.api->stc_cmd_req(2, &mcmd);

	mcmd.cmd = FUN_CODE_W_R_MULTIPLE_REG;
	mb.obj03.api->stc_cmd_req(3, &mcmd);

	mcmd.cmd = FUN_CODE_WRITE_MULTIPLE_REG;
	mb.obj03.api->stc_cmd_req(4, &mcmd);

	mcmd.cmd = FUN_CODE_WRITE_MULTIPLE_COIL;
	mb_tst.pv_w[0] = 0;
	mb.obj03.api->stc_cmd_req(5, &mcmd);

	// task handle
	for (;;)
	{
		osEvent event;

		// wait modbus event
		event = osSignalWait(0, 1000);

		(void)event;

		mb_poll(&mb.obj03);
		mb_poll(&mb.obj04);

		mb_tst.obj_size = sizeof(mb.obj03);
	}
}

/******************************************************************************
 * @brief   mb handle.
 * @param   none
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void qc_callback(uu8 site, uu8 err){
	if(err)
	{
		NOP1();
	}
}
void qc_task(const void *argv)
{
	qc_cmd_type mcmd;
	uu8 bdone;

	// master config
	//qc01_Init(QC_MODE_MASTER, 115200);
	//mb.qc01.os_event_send = mb_os_send;
	//mb.qc01.et_sv = 200;
	//mb.qc01.tout_sv = 240;

	// master config
	qc04_Init(QC_MODE_SLAVE, 115200);
	mb.qc04.os_event_send = mb_os_send;

	// master config
	qc03_Init(QC_MODE_MASTER, 115200);
	mb.qc03.os_event_send = mb_os_send;

	// cmd config
	mcmd.id = 1;
	mcmd.wdat = mb_tst.pv_w;
	mcmd.rdat = mb_tst.pv_r;
	mcmd.wa = word_make(0, 5);
	mcmd.wn = 4;
	mcmd.ra = 253;
	mcmd.rn = 4;
	mcmd.callback = qc_callback;
	mcmd.attr = QC_MB_ATTR_HOLD_RW;
	mqc_stc_cmd_req(&mb.qc03, 0, &mcmd);
	mqc_stc_cmd_req(&mb.qc01, 0, &mcmd);

	mcmd.wa = word_make(2, 5);
	mcmd.wn = 0;
	mqc_stc_cmd_req(&mb.qc03, 1, &mcmd);
	mqc_stc_cmd_req(&mb.qc01, 1, &mcmd);

	mcmd.wa = word_make(12, 16);
	mcmd.wn = 3;
	mqc_stc_cmd_req(&mb.qc03, 2, &mcmd);
	mqc_stc_cmd_req(&mb.qc01, 1, &mcmd);

	// task handle
	for (;;)
	{
		osEvent event;

		// wait modbus event
		event = osSignalWait(0, 1000);

		(void)event;

		qc_mb_poll(&mb.qc03);

		qc_mb_poll(&mb.qc04);

		//qc_mb_poll(&mb.qc01);

		mb_tst.obj_size = sizeof(mb.qc03);

		if ((mb.qc04.success_cnt & 0x3) == 0)
		{
			if (!bdone)
			{
				bdone = 1;
				mcmd.wa = word_make(14, 32);
				mqc_dyna_cmd_req(&mb.qc03, &mcmd);
				mqc_dyna_cmd_req(&mb.qc01, &mcmd);
			}
		}
		else
		{
			bdone = 0;
		}
	}
}
